﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls.Primitives;
using System.Windows.Controls;
using System.Windows.Media;

namespace ICodeShare.UI.Controls.Assists
{
   /// <summary>
   /// 日历控件附加属性
   /// </summary>
    public class CalendarAssist
    {
        #region DisplayDate 显示时间

        /// <summary>
        /// Allows on (IsChecked) content to be provided on supporting <see cref="ToggleButton"/> styles.
        /// </summary>
        [AttachedPropertyBrowsableForType(typeof(CalendarButton))]
        [AttachedPropertyBrowsableForType(typeof(CalendarDayButton))]
        [AttachedPropertyBrowsableForType(typeof(CalendarItem))]
        public static DateTime GetDisplayDate(DependencyObject element)
        {
            return (DateTime)element.GetValue(DisplayDateProperty);
        }

        /// <summary>
        /// Allows on (IsChecked) content to be provided on supporting <see cref="ToggleButton"/> styles.
        /// </summary>
        /// <param name="element"></param>
        /// <param name="value"></param>
        public static void SetDisplayDate(DependencyObject element, DateTime value)
        {
            element.SetValue(DisplayDateProperty, value);
        }

        /// <summary>
        /// Allows on (IsChecked) content to be provided on supporting <see cref="ToggleButton"/> styles.
        /// </summary>
        public static readonly DependencyProperty DisplayDateProperty = DependencyProperty.RegisterAttached(
            "DisplayDate",
            typeof(DateTime),
            typeof(CalendarAssist),
            new FrameworkPropertyMetadata(DateTime.MinValue, FrameworkPropertyMetadataOptions.Inherits));

        #endregion

        #region CanMoveToday 是否可清空

        /// <summary>
        /// Get where show the shadow for waiting data
        /// </summary>
        [AttachedPropertyBrowsableForType(typeof(Calendar))]
        public static bool GetCanMoveToday(DependencyObject element)
        {
            return (bool)element.GetValue(CanMoveTodayProperty);
        }

        /// <summary>
        /// Set where show the shadow for waiting data
        /// </summary>
        public static void SetCanMoveToday(DependencyObject element, bool value)
        {
            element.SetValue(CanMoveTodayProperty, value);
        }

        /// <summary>
        /// DependencyProperty for <see cref="CanMoveToday" /> property.
        /// </summary>
        public static readonly DependencyProperty CanMoveTodayProperty = DependencyProperty.RegisterAttached(
            "CanMoveToday",
            typeof(bool),
            typeof(CalendarAssist),
            new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.Inherits));

        #endregion CanMoveToday 是否可清空

        #region IsMoveTodayButtonBehaviorEnabled 清空按钮的命令是否可用

        /// <summary>
        /// Gets the clear text button behavior.
        /// </summary>
        [AttachedPropertyBrowsableForType(typeof(Button))]
        public static bool GetIsMoveTodayButtonBehaviorEnabled(Button d)
        {
            return (bool)d.GetValue(IsMoveTodayButtonBehaviorEnabledProperty);
        }

        /// <summary>
        /// Sets the clear text button behavior.
        /// </summary>
        [AttachedPropertyBrowsableForType(typeof(Button))]
        public static void SetIsMoveTodayButtonBehaviorEnabled(Button obj, bool value)
        {
            obj.SetValue(IsMoveTodayButtonBehaviorEnabledProperty, value);
        }

        /// <summary>
        /// The clear text button behavior property. It sets a click event to the button if the value is true.
        /// </summary>
        public static readonly DependencyProperty IsMoveTodayButtonBehaviorEnabledProperty = DependencyProperty.RegisterAttached(
            "IsMoveTodayButtonBehaviorEnabled",
            typeof(bool),
            typeof(CalendarAssist),
            new FrameworkPropertyMetadata(false, IsMoveTodayButtonBehaviorEnabledChanged));


        private static void IsMoveTodayButtonBehaviorEnabledChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var todayButton = d as Button;
            if (e.OldValue != e.NewValue && todayButton != null)
            {
                todayButton.Click -= TodayButtonClicked;
                if ((bool)e.NewValue)
                {
                    todayButton.Click += TodayButtonClicked;
                }
            }
        }

        public static void TodayButtonClicked(object sender, RoutedEventArgs e)
        {
            var button = ((Button)sender);
            var parent = VisualTreeHelper.GetParent(button);
            while (!(parent is Calendar))
            {
                parent = VisualTreeHelper.GetParent(parent);
            }

            if (GetCanMoveToday(parent))
            {
                if (parent is Calendar)
                {
                    ((Calendar)parent).SelectedDate=DateTime.Today;
                }
            }
        }
        #endregion

        #region PreviousYear 上一年

        #region CanPreviousYear 是否可切换上一年

        /// <summary>
        /// Get where show the shadow for waiting data
        /// </summary>
        [AttachedPropertyBrowsableForType(typeof(Calendar))]
        public static bool GetCanPreviousYear(DependencyObject element)
        {
            return (bool)element.GetValue(CanPreviousYearProperty);
        }

        /// <summary>
        /// Set where show the shadow for waiting data
        /// </summary>
        public static void SetCanPreviousYear(DependencyObject element, bool value)
        {
            element.SetValue(CanPreviousYearProperty, value);
        }

        /// <summary>
        /// DependencyProperty for <see cref="CanPreviousYear" /> property.
        /// </summary>
        public static readonly DependencyProperty CanPreviousYearProperty = DependencyProperty.RegisterAttached(
            "CanPreviousYear",
            typeof(bool),
            typeof(CalendarAssist),
            new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.Inherits));

        #endregion CanPreviousYear 是否可清空

        #region IsPreviousYearButtonBehaviorEnabled 切换上一年按钮的命令是否可用

        /// <summary>
        /// Gets the clear text button behavior.
        /// </summary>
        [AttachedPropertyBrowsableForType(typeof(Button))]
        public static bool GetIsPreviousYearButtonBehaviorEnabled(Button d)
        {
            return (bool)d.GetValue(IsPreviousYearButtonBehaviorEnabledProperty);
        }

        /// <summary>
        /// Sets the clear text button behavior.
        /// </summary>
        [AttachedPropertyBrowsableForType(typeof(Button))]
        public static void SetIsPreviousYearButtonBehaviorEnabled(Button obj, bool value)
        {
            obj.SetValue(IsPreviousYearButtonBehaviorEnabledProperty, value);
        }

        /// <summary>
        /// The clear text button behavior property. It sets a click event to the button if the value is true.
        /// </summary>
        public static readonly DependencyProperty IsPreviousYearButtonBehaviorEnabledProperty = DependencyProperty.RegisterAttached(
            "IsPreviousYearButtonBehaviorEnabled",
            typeof(bool),
            typeof(CalendarAssist),
            new FrameworkPropertyMetadata(false, IsPreviousYearButtonBehaviorEnabledChanged));


        private static void IsPreviousYearButtonBehaviorEnabledChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var previousYearButton = d as Button;
            if (e.OldValue != e.NewValue && previousYearButton != null)
            {
                previousYearButton.Click -= PreviousYearButtonClicked;
                if ((bool)e.NewValue)
                {
                    previousYearButton.Click += PreviousYearButtonClicked;
                }
            }
        }

        public static void PreviousYearButtonClicked(object sender, RoutedEventArgs e)
        {
            var button = ((Button)sender);
            var parent = VisualTreeHelper.GetParent(button);
            while (!(parent is Calendar))
            {
                parent = VisualTreeHelper.GetParent(parent);
            }

            if (GetCanPreviousYear(parent))
            {
                if (parent is Calendar)
                {
                    Calendar owerCalendar = (Calendar)parent;
                    int year = owerCalendar.DisplayDate.Year;
                    int month = owerCalendar.DisplayDate.Month;
                    switch (owerCalendar.DisplayMode)
                    {
                        case CalendarMode.Month:
                        case CalendarMode.Year:
                            owerCalendar.DisplayDate = new DateTime(year - 1, month, 1);
                            break;
                        case CalendarMode.Decade:
                            owerCalendar.DisplayDate = new DateTime(year - 10, month, 1);
                            break;
                        default:
                            break;
                    }
                }
              
            }
        }
        #endregion

        #endregion

        #region PreviousMonth 上一个月
        
        #region CanPreviousMonth 是否切换上个月

        /// <summary>
        /// Get where show the shadow for waiting data
        /// </summary>
        [AttachedPropertyBrowsableForType(typeof(Calendar))]
        public static bool GetCanPreviousMonth(DependencyObject element)
        {
            return (bool)element.GetValue(CanPreviousMonthProperty);
        }

        /// <summary>
        /// Set where show the shadow for waiting data
        /// </summary>
        public static void SetCanPreviousMonth(DependencyObject element, bool value)
        {
            element.SetValue(CanPreviousMonthProperty, value);
        }

        /// <summary>
        /// DependencyProperty for <see cref="CanPreviousMonth" /> property.
        /// </summary>
        public static readonly DependencyProperty CanPreviousMonthProperty = DependencyProperty.RegisterAttached(
            "CanPreviousMonth",
            typeof(bool),
            typeof(CalendarAssist),
            new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.Inherits));

        #endregion CanPreviousMonth 是否可清空

        #region IsPreviousMonthButtonBehaviorEnabled 切换上个月按钮的命令是否可用

        /// <summary>
        /// Gets the clear text button behavior.
        /// </summary>
        [AttachedPropertyBrowsableForType(typeof(Button))]
        public static bool GetIsPreviousMonthButtonBehaviorEnabled(Button d)
        {
            return (bool)d.GetValue(IsPreviousMonthButtonBehaviorEnabledProperty);
        }

        /// <summary>
        /// Sets the clear text button behavior.
        /// </summary>
        [AttachedPropertyBrowsableForType(typeof(Button))]
        public static void SetIsPreviousMonthButtonBehaviorEnabled(Button obj, bool value)
        {
            obj.SetValue(IsPreviousMonthButtonBehaviorEnabledProperty, value);
        }

        /// <summary>
        /// The clear text button behavior property. It sets a click event to the button if the value is true.
        /// </summary>
        public static readonly DependencyProperty IsPreviousMonthButtonBehaviorEnabledProperty = DependencyProperty.RegisterAttached(
            "IsPreviousMonthButtonBehaviorEnabled",
            typeof(bool),
            typeof(CalendarAssist),
            new FrameworkPropertyMetadata(false, IsPreviousMonthButtonBehaviorEnabledChanged));


        private static void IsPreviousMonthButtonBehaviorEnabledChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var previousMonthButton = d as Button;
            if (e.OldValue != e.NewValue && previousMonthButton != null)
            {
                previousMonthButton.Click -= PreviousMonthButtonClicked;
                if ((bool)e.NewValue)
                {
                    previousMonthButton.Click += PreviousMonthButtonClicked;
                }
            }
        }

        public static void PreviousMonthButtonClicked(object sender, RoutedEventArgs e)
        {
            var button = ((Button)sender);
            var parent = VisualTreeHelper.GetParent(button);
            while (!(parent is Calendar))
            {
                parent = VisualTreeHelper.GetParent(parent);
            }

            if (GetCanPreviousYear(parent))
            {
                if (parent is Calendar)
                {
                    Calendar owerCalendar = (Calendar)parent;
                    int year = owerCalendar.DisplayDate.Year;
                    int month = owerCalendar.DisplayDate.Month;
                    switch (owerCalendar.DisplayMode)
                    {
                        case CalendarMode.Month:
                            if (month == 1)
                            {
                                owerCalendar.DisplayDate = new DateTime(year - 1, 12, 1);
                            }
                            else
                            {
                                owerCalendar.DisplayDate = new DateTime(year, month - 1, 1);
                            }
                            break;
                    }
                }

            }
        }
        #endregion

        #endregion

        #region NextMonth 下一个月

        #region CanNextMonth 是否可切换下个月

        /// <summary>
        /// Get where show the shadow for waiting data
        /// </summary>
        [AttachedPropertyBrowsableForType(typeof(Calendar))]
        public static bool GetCanNextMonth(DependencyObject element)
        {
            return (bool)element.GetValue(CanNextMonthProperty);
        }

        /// <summary>
        /// Set where show the shadow for waiting data
        /// </summary>
        public static void SetCanNextMonth(DependencyObject element, bool value)
        {
            element.SetValue(CanNextMonthProperty, value);
        }

        /// <summary>
        /// DependencyProperty for <see cref="CanNextMonth" /> property.
        /// </summary>
        public static readonly DependencyProperty CanNextMonthProperty = DependencyProperty.RegisterAttached(
            "CanNextMonth",
            typeof(bool),
            typeof(CalendarAssist),
            new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.Inherits));

        #endregion CanNextMonth 是否可清空

        #region IsNextMonthButtonBehaviorEnabled 切换下个月按钮的命令是否可用

        /// <summary>
        /// Gets the clear text button behavior.
        /// </summary>
        [AttachedPropertyBrowsableForType(typeof(Button))]
        public static bool GetIsNextMonthButtonBehaviorEnabled(Button d)
        {
            return (bool)d.GetValue(IsNextMonthButtonBehaviorEnabledProperty);
        }

        /// <summary>
        /// Sets the clear text button behavior.
        /// </summary>
        [AttachedPropertyBrowsableForType(typeof(Button))]
        public static void SetIsNextMonthButtonBehaviorEnabled(Button obj, bool value)
        {
            obj.SetValue(IsNextMonthButtonBehaviorEnabledProperty, value);
        }

        /// <summary>
        /// The clear text button behavior property. It sets a click event to the button if the value is true.
        /// </summary>
        public static readonly DependencyProperty IsNextMonthButtonBehaviorEnabledProperty = DependencyProperty.RegisterAttached(
            "IsNextMonthButtonBehaviorEnabled",
            typeof(bool),
            typeof(CalendarAssist),
            new FrameworkPropertyMetadata(false, IsNextMonthButtonBehaviorEnabledChanged));


        private static void IsNextMonthButtonBehaviorEnabledChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var nextMonthButton = d as Button;
            if (e.OldValue != e.NewValue && nextMonthButton != null)
            {
                nextMonthButton.Click -= NextMonthButtonClicked;
                if ((bool)e.NewValue)
                {
                    nextMonthButton.Click += NextMonthButtonClicked;
                }
            }
        }

        public static void NextMonthButtonClicked(object sender, RoutedEventArgs e)
        {
            var button = ((Button)sender);
            var parent = VisualTreeHelper.GetParent(button);
            while (!(parent is Calendar))
            {
                parent = VisualTreeHelper.GetParent(parent);
            }

            if (GetCanPreviousYear(parent))
            {
                if (parent is Calendar)
                {
                    Calendar owerCalendar = (Calendar)parent;
                    int year = owerCalendar.DisplayDate.Year;
                    int month = owerCalendar.DisplayDate.Month;
                    switch (owerCalendar.DisplayMode)
                    {
                        case CalendarMode.Month:
                            if (month == 12)
                            {
                                owerCalendar.DisplayDate = new DateTime(year + 1, 1, 1);
                            }
                            else
                            {
                                owerCalendar.DisplayDate = new DateTime(year, month + 1, 1);
                            }
                            break;
                    }
                }

            }
        }
        #endregion

        #endregion

        #region NextYear 下一年

        #region CanNextYear 是否可切换下一年

        /// <summary>
        /// Get where show the shadow for waiting data
        /// </summary>
        [AttachedPropertyBrowsableForType(typeof(Calendar))]
        public static bool GetCanNextYear(DependencyObject element)
        {
            return (bool)element.GetValue(CanNextYearProperty);
        }

        /// <summary>
        /// Set where show the shadow for waiting data
        /// </summary>
        public static void SetCanNextYear(DependencyObject element, bool value)
        {
            element.SetValue(CanNextYearProperty, value);
        }

        /// <summary>
        /// DependencyProperty for <see cref="CanNextYear" /> property.
        /// </summary>
        public static readonly DependencyProperty CanNextYearProperty = DependencyProperty.RegisterAttached(
            "CanNextYear",
            typeof(bool),
            typeof(CalendarAssist),
            new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.Inherits));

        #endregion CanNextYear 是否可清空

        #region IsNextYearButtonBehaviorEnabled 切换下一年按钮的命令是否可用

        /// <summary>
        /// Gets the clear text button behavior.
        /// </summary>
        [AttachedPropertyBrowsableForType(typeof(Button))]
        public static bool GetIsNextYearButtonBehaviorEnabled(Button d)
        {
            return (bool)d.GetValue(IsNextYearButtonBehaviorEnabledProperty);
        }

        /// <summary>
        /// Sets the clear text button behavior.
        /// </summary>
        [AttachedPropertyBrowsableForType(typeof(Button))]
        public static void SetIsNextYearButtonBehaviorEnabled(Button obj, bool value)
        {
            obj.SetValue(IsNextYearButtonBehaviorEnabledProperty, value);
        }

        /// <summary>
        /// The clear text button behavior property. It sets a click event to the button if the value is true.
        /// </summary>
        public static readonly DependencyProperty IsNextYearButtonBehaviorEnabledProperty = DependencyProperty.RegisterAttached(
            "IsNextYearButtonBehaviorEnabled",
            typeof(bool),
            typeof(CalendarAssist),
            new FrameworkPropertyMetadata(false, IsNextYearButtonBehaviorEnabledChanged));


        private static void IsNextYearButtonBehaviorEnabledChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var nextYearButton = d as Button;
            if (e.OldValue != e.NewValue && nextYearButton != null)
            {
                nextYearButton.Click -= NextYearButtonClicked;
                if ((bool)e.NewValue)
                {
                    nextYearButton.Click += NextYearButtonClicked;
                }
            }
        }

        public static void NextYearButtonClicked(object sender, RoutedEventArgs e)
        {
            var button = ((Button)sender);
            var parent = VisualTreeHelper.GetParent(button);
            while (!(parent is Calendar))
            {
                parent = VisualTreeHelper.GetParent(parent);
            }

            if (GetCanNextYear(parent))
            {
                if (parent is Calendar)
                {
                    Calendar owerCalendar = (Calendar)parent;
                    int year = owerCalendar.DisplayDate.Year;
                    int month = owerCalendar.DisplayDate.Month;
                    switch (owerCalendar.DisplayMode)
                    {
                        case CalendarMode.Month:
                        case CalendarMode.Year:
                            owerCalendar.DisplayDate = new DateTime(year + 1, month, 1);
                            break;
                        case CalendarMode.Decade:
                            owerCalendar.DisplayDate = new DateTime(year + 10, month, 1);
                            break;
                        default:
                            break;
                    }
                }

            }
        }
        #endregion

        #endregion
    }
}
